package action;

import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import manager.PasswordIncorrect;
import manager.UserManager;
import manager.UserNotExist;
import model.User;
import static util.ConstantStringTable.*;
import static util.MD5.*;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.*;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.validator.annotations.*;

/**
 * 
 * Process the request of logging in.
 * 
 * @author Cylixstar
 * 
 */
@SuppressWarnings("serial")
@Action("login")
@Results( { 
		@Result(name = "success", type="redirect",location = "/mainPanel.jsp"),
		@Result(name = "failed", location = "/index.jsp"),
		@Result(name = "input", location = "/index.jsp") 
		})
public class LoginAction extends ActionSupport {

	public static final String FAILED = "failed";
	private String username;
	private String password;
	private boolean remember;
	
	@SuppressWarnings("unchecked")
	@Override
	@Validations(
				requiredStrings={
						@RequiredStringValidator(type = ValidatorType.SIMPLE,fieldName="username",
								message="Username must not be empty."),
						@RequiredStringValidator(type = ValidatorType.SIMPLE,fieldName="password",
									message="Password must not be empty.")
				},
				regexFields ={
						@RegexFieldValidator(type = ValidatorType.SIMPLE,fieldName="username",expression="[\\w-]{1,25}", 
								message="The username can only consist of alphabetic ,numeric character, underline and hypen as longer as 25 characters."),
						@RegexFieldValidator(type = ValidatorType.SIMPLE,fieldName="password",expression="[\\w-]{6,25}", 
								message="The password can only consist of alphabetic ,numeric character, underline and hypen " 
										+ "as longer as 25 characters and at least 6 characters.")
				}
			)
	public String execute() throws Exception {
		String md5Password= getMD5(getPassword());
		User loginUser;
		try{
			loginUser = UserManager.getUserManager().login(username, md5Password);
		}catch(UserNotExist userNotExist){
			addFieldError("username", "User not exists,please check your user name.");
			return FAILED;
		}catch(PasswordIncorrect pwdIncorrect){
			addActionMessage("Password does not match user,please check again.");
			return FAILED;
		}
		ActionContext ctx = ActionContext.getContext();
		Map session = ctx.getSession();
		session.put(LOGIN_USER, loginUser);
		HttpServletResponse response = (HttpServletResponse)ctx.get(ServletActionContext.HTTP_RESPONSE);
		
		if(isRemember()){
			//Remember the login for one week
			Cookie ck = new Cookie(LOGIN_COOKIE,loginUser.getUsername() + ":" + md5Password);
			ck.setMaxAge(60 * 60 * 24 * 7);
			response.addCookie(ck);
			
		}
		
		return SUCCESS;
	}

	public String getUsername() {
		return username;
	}

	public String getPassword() {
		return password;
	}

	public boolean isRemember() {
		return remember;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public void setRemember(boolean remember) {
		this.remember = remember;
	}

}
